<?php

namespace app\shop\model;

use app\shop\library\ShopLogHelper;
use think\Collection;
use think\db\BaseQuery;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;
use think\Paginator;

abstract class BaseModel extends Model
{
    // 设置JSON数据返回数组
    protected $jsonAssoc = true;

    // 设置软删除字段默认值
    protected $defaultSoftDelete = 0;

    // 设置默认时间字段类型
    protected $type = [
        'create_time' => 'timestamp:Y-m-d H:i:s',
        'update_time' => 'timestamp:Y-m-d H:i:s',
        'delete_time' => 'timestamp:Y-m-d H:i:s',
    ];

    public function __construct(object|array $data = [])
    {
        parent::__construct($data);

        $this->type = array_merge($this->type, $this->setType());
    }

    public function setType(): array
    {
        return [];
    }

    /**
     * 获取模型baseQuery对象
     * @return BaseQuery
     */
    public static function getQuery(): BaseQuery
    {
        return self::query();
    }

    /** @noinspection PhpUnused */
    public function scoreWithoutRecordTime($query)
    {
        return $query->withoutField(['create_time', 'update_time']);
    }

    /**
     * 列表查询
     * @param BaseQuery $query   模型query对象
     * @param bool      $toArray 转化为数组并自动处理null值
     * @return Collection|array
     */
    public static function listQuery(BaseQuery $query, bool $toArray = true): Collection|array
    {
        try {
            $result = $query->select();
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            $result = [];
            ShopLogHelper::error('列表查询失败', ['query' => $query], $e);
        }

        if ($toArray && !is_array($result)) {
            $result = $result->toArray();
            self::dealNull($result);
        }

        return $result;
    }

    /**
     * 分页查询
     * @param BaseQuery $query    模型query对象
     * @param bool      $toArray  转化为数组并自动处理null值
     * @param int|null  $pageSize 分页参数
     *                            <br>默认获取page_size
     * @return Paginator|array
     */
    public static function paginateListQuery(BaseQuery $query, bool $toArray = false, int $pageSize = null): Paginator|array
    {
        $pageSize = $pageSize ?: request()->param('page_size', 10);

        try {
            $result = $query->paginate($pageSize);
        } catch (DbException $e) {
            $result = [];
            ShopLogHelper::error('分页查询失败', ['query' => $query], $e);
        }

        if ($toArray && !is_array($result)) {
            $result = $result->toArray();
            self::dealNull($result);
        }

        return $result;
    }

    /**
     * 处理字段null值为空字符
     * @param array $data
     * return void
     */
    public static function dealNull(array $data): void
    {
        array_walk_recursive($data, function (&$value) {
            if (is_null($value)) {
                $value = '';
            }
        });
    }
}
